﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows;

using System.IO;
using System.IO.IsolatedStorage;

using System.Runtime.Serialization;
using System.ComponentModel;
using System.Security.Permissions;
using System.Windows.Media.Imaging;
using System.Windows.Controls;

using System.Xml.Serialization;
using slTestingStreaming.Framework;
using slTestingStreaming.Model.DTO;
using System.Runtime.Serialization.Json;
using System.Windows.Threading;

namespace slTestingStreaming.Model.Manager
{
    public partial class TwitterManager : Bindable
    {

        public event EventHandler ProfileRetrieved;

        private Yedda.Twitter yd;

        public ObservableCollection<Tweeter> Friends {get; set;}
        public ObservableCollection<TweetGeo> FriendStatuses { get; set; }
        public ObservableCollection<TweetGeo> ProfileStatuses { get; set; }
        
        public Tweeter SelectedProfile { get; set; }

        public string NextFriendsCursor { get; set; }
        public string NextFriendStatusesCursor { get; set; }

        public int FriendStatusesCount { get; set; }


        public DispatcherTimer dt;

        private bool RefreshFriendsTimeline = false;

        private void InitYedda()
        {
            yd = new Yedda.Twitter();
            NextFriendsCursor = "-1";
            NextFriendStatusesCursor = "-1";
            Friends = new ObservableCollection<Tweeter>();
            FriendStatuses = new ObservableCollection<TweetGeo>();
            ProfileStatuses = new ObservableCollection<TweetGeo>();

            dt = new DispatcherTimer();
            dt.Interval = TimeSpan.FromMinutes(1);
            dt.Tick += new EventHandler(dt_Tick);
            dt.Start();
        }

        void dt_Tick(object sender, EventArgs e)
        {
            if(RefreshFriendsTimeline) GetFriendStatuses(this.StreamingUser.UserName, this.StreamingUser.Password, this.NextFriendStatusesCursor);
        }

        #region FRIENDS
        public void GetFriends(string usr, string pwd, string cursor)
        {
            yd.GetFriendsComplete += new EventHandler(yd_GetFriendsComplete);
            yd.GetFriendsAsJSONWithCursor(usr, pwd, cursor);
        }

        void yd_GetFriendsComplete(object sender, EventArgs e)
        {
            yd.GetFriendsComplete -= yd_GetFriendsComplete;

            string message = (string)sender;
            using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(message)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Tweeters));
                Tweeters item = (Tweeters)serializer.ReadObject(ms);
                NextFriendsCursor = item.next_cursor.ToString() ;

                Dispatcher.BeginInvoke(() =>
                {
                    foreach (Tweeter t in item.users)
                    {
                        this.Friends.Add(t);
                    }

                });


            }
        }
        #endregion


        #region FRIENDS STATUSES
        public void GetFriendStatuses(string usr, string pwd, string cursor)
        {
            yd.GetFriendsTimelineComplete += new EventHandler(yd_GetFriendsTimelineComplete);
            //yd.GetFriendsTimelineAsJSONWithCursor(usr, pwd, cursor);
            yd.GetFriendsTimelineAsJSON(usr, pwd);
            RefreshFriendsTimeline = true;
        }

        

        
        void yd_GetFriendsTimelineComplete(object sender, EventArgs e)
        {
            yd.GetFriendsTimelineComplete -= yd_GetFriendsTimelineComplete;

            string message = (string)sender;
            using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(message)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<TweetGeo>));
                List<TweetGeo> items = (List<TweetGeo>)serializer.ReadObject(ms);
                //NextFriendsCursor = item.next_cursor.ToString();
                items.Reverse(0, items.Count);

                Dispatcher.BeginInvoke(() =>
                {
                    foreach (TweetGeo t in items)
                    {
                        var id = this.FriendStatuses.Where(x => x.id == t.id).Select(y => y.id);
                        if (id != null && id.Count()==0)
                        {
                            if (FriendStatuses.Count == 0) this.FriendStatuses.Add(t);
                            else this.FriendStatuses.Insert(0, t);

                            this.FriendStatusesCount++;
                            this.NotifyPropertyChanged("FriendStatusesCount");
                        }
                    }

                });


            }
        }
        #endregion


        #region PROFILE
        public void GetProfile(string usr, string pwd, string profile)
        {
            this.ProfileStatuses.Clear();
            this.SelectedProfile = null;


            yd.ShowComplete += new EventHandler(yd_ShowComplete);
            yd.ShowAsJSON(usr, pwd, profile);
        }

        void yd_ShowComplete(object sender, EventArgs e)
        {
            yd.ShowComplete -= yd_ShowComplete;

            string message = (string)sender;
            using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(message)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Tweeter));
                Tweeter item = (Tweeter)serializer.ReadObject(ms);


                Dispatcher.BeginInvoke(() =>
                {
                    //Profile Image
                    //string[] parts = item.profile_image_url.Split("/".ToCharArray());
                    //parts[parts.Length - 1] = "twitterProfilePhoto_bigger.jpg";
                    //string url = string.Empty;
                    //foreach (string part in parts)
                    //{
                    //    url += part + "/";
                    //}
                    //url = url.Substring(0, url.Length - 1);
                    //item.profile_image_url = url;

                    this.SelectedProfile = item;


                    this.NotifyPropertyChanged("SelectedProfile");
                    if (ProfileRetrieved != null) ProfileRetrieved(null, null);

                });


            }
        }
        #endregion

        #region PROFILE DIRECT TWEETS
        public void GetProfileDirectMessages(string usr, string pwd, string profile)
        {
            //yd.GetUserTimelineComplete += new EventHandler(yd_GetUserTimelineComplete);
            //yd.GetUserTimelineAsJSON(usr, pwd, profile);
        }
        #endregion

        #region PROFILE TWEETS
        public void GetProfileStatuses(string usr, string pwd, string profile)
        {
            yd.GetUserTimelineComplete += new EventHandler(yd_GetUserTimelineComplete);
            yd.GetUserTimelineAsJSON(usr, pwd, profile);
        }



        void yd_GetUserTimelineComplete(object sender, EventArgs e)
        {
            yd.GetUserTimelineComplete -= yd_GetUserTimelineComplete;

            string message = (string)sender;
            using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(message)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<TweetGeo>));
                List<TweetGeo> items = (List<TweetGeo>)serializer.ReadObject(ms);

                items.Reverse(0, items.Count);

                Dispatcher.BeginInvoke(() =>
                {
                    
                    foreach (TweetGeo item in items)
                    {
                        if (ProfileStatuses.Count == 0) this.ProfileStatuses.Add(item);
                        else this.ProfileStatuses.Insert(0, item);
                    }

                });


            }
        }
        #endregion

        #region SendTweet
        public void SendTweet(string usr, string pwd, string tweet)
        {
            if (tweet.Trim().Length == 0) return;
            string ret = yd.Update(usr, pwd, tweet, Yedda.Twitter.OutputFormatType.JSON);

        }
        #endregion
    }
}
